package test.msm;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;

import hyl.base.cache2.ExToken;
import hyl.base.cache2.ExTokenFactory;
import hyl.core.MyFun;
import hyl.core.conf.MyConfig;
import hyl.core.safe.MyHash;
import hyl.core.safe.MyRsa;
import hyl.ext.base.SessionFactory;

// key 签名模式
public class testsso2 {
	public static void main(String[] args) {
		testsso2 tt2 = new testsso2();
		tt2.f1_1_b();

	}

	PublicKey pbk;
	PrivateKey pik;
	String 签钥 = "123456";
	String 公钥;
	String 私钥;
	String appidB = "123";
	ExToken tokenA = null;

	ExTokenFactory listeta = new ExTokenFactory(60000);// 60s过期
	ExTokenFactory listetb = new ExTokenFactory(10000);// 10s过期
	Map<String, String> _apps = new HashMap<>();
	SessionFactory _sf;

	public testsso2() {
		_sf = SessionFactory.getInstance();
		_apps.put("123", "123456");
		公钥 = MyConfig.loadTxt("cert/公钥.txt");
		System.out.println(公钥);
		pbk = MyRsa.generate64公钥(公钥);
		私钥 = MyConfig.loadTxt("cert/私钥.txt");
		System.out.println(私钥);
		pik = MyRsa.generate64私钥(私钥);
	}

	/*
	 * 提取 b本地tokena 创建一个tokenb 发送给a a 接收tokenb ,appidb, tokena
	 * 
	 */
	public void f1_1_b() {
		String sessionA=null;
		String urlb = "http://www.163.com";
		ExToken tokenB = listetb.createAdd();
		String stamp = tokenB.getStampstr();
		String tokenbm = MyRsa.f公钥加密uri(pbk, tokenB.getId());
		String sign = MyHash.getInsSHA1().parse(签钥 + stamp);
		MyFun.print("f1_1_b()",sessionA, "\r\n", tokenB.getId(), "\r\n", tokenbm, "\r\n", stamp, sign);
		f1_2_a(sessionA, tokenbm, urlb, appidB, stamp, sign);
	}

	/*
	 * a: 查询 tokena 是否存在,
	 * 
	 * 如果 验证签名 () 正确
	 * 
	 * 签名无法解决tokenb 加密的问题 对方如果模拟a网站 获取 tokenb 就可以直接登录b
	 * 
	 */
	public void f1_2_a(String sessionA, String tokenBm, String urlb, String appid, String stamp, String sign) {
		System.out.println("f1_2_a()");
		String key = _apps.get(appid);
		boolean flag = MyHash.getInsSHA1().verify(key + stamp, sign);
		// 签名不正确直接扔掉
		if (!flag)
			return;

		// 先验证签名再解码 ,否则每个都解码 遇到暴力攻击非常麻烦
		String tokenB = MyRsa.f私钥解密uri(pik, tokenBm);
		MyFun.print("tokenB", tokenB);
		// 验证 tokena
		if (!MyFun.isBlank(sessionA) && SessionFactory.isLogin(sessionA)) {
			f1_3_b(tokenB, urlb);
		} else {
			ExToken eta = listeta.createAdd();
			eta.setI可用次数(3);
			f1_3_a(eta, tokenB, urlb);
		}
	}

	/*
	 * 登录 a 后才能重定向到b
	 * 
	 */
	public void f1_3_a(ExToken eta, String tokenB, String urlb) {
		System.out.println("f1_3_a()");
		if (eta.getI可用次数() == 0) {
			listeta.remove(eta.getId());
			// 跳转到失败页面
			return;
		}
		
		String user = "10000";
		String pass = "111";
		f1_3_a_login(eta.getId(), tokenB, urlb, user, pass);
	}

	// 登录验证
	public void f1_3_a_login(String tokenA, String tokenB, String urlb, String user, String pass) {
		System.out.println("f1_3_a_login()");
		ExToken eta = listeta.get(tokenA);
		if (user.equals("10000") && pass.equals("111")) {
			f1_3_b(tokenB, urlb);
		} else {
			f1_3_a(eta, tokenB, urlb);
		}
	}

	// 定向到b指定页
	public void f1_3_b(String tokenB, String urlb) {
		System.out.println("f1_3_b()");
		
		if (listetb.contain(tokenB)) {
			listetb.remove(tokenB);
			MyFun.print("成功登录", tokenB, urlb);
		}else {
		   //定向到 404.html
		}
	}

}
